package craky.keeper.user;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.border.EmptyBorder;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

import craky.component.JImagePane;
import craky.componentc.JCButton;
import craky.componentc.JCComboBox;
import craky.componentc.JCDialog;
import craky.componentc.JCLabel;
import craky.componentc.JCLimitedPassword;
import craky.componentc.JCMessageBox;
import craky.componentc.JCTextField;
import craky.keeper.EmptyComponent;
import craky.keeper.KeeperApp;
import craky.keeper.KeeperConst;
import craky.keeper.LoginFrame;
import craky.keeper.util.KeeperUtil;
import craky.layout.LineLayout;
import craky.util.UIUtil;

public class UserInfoDialog extends JCDialog implements ActionListener {
	private static final long serialVersionUID = 4787072148793183017L;
	private JComponent content;
	private JCButton btnOk;
	private JCButton btnCancel;
	private JCTextField txtUser;
	private JCComboBox cbPurview;
	private JCLimitedPassword txtOld;
	private JCLimitedPassword txtNew;
	private JCLimitedPassword txtCheck;
	private String userName;
	private User user;
	private boolean needOldPassword;
	private boolean isAdd;

	public UserInfoDialog(KeeperApp keeper, Window owner, String userName,
			boolean needOldPassword) {
		super(owner, userName == null ? "添加用户" : "修改密码",
				Dialog.ModalityType.DOCUMENT_MODAL);
		this.userName = userName;
		this.needOldPassword = needOldPassword;
		this.isAdd = (userName == null);
		initUI();
		String bannerName = null;

		if (owner == null) {
			setIconImage(KeeperUtil.getImage("logo_16.png"));
		}

		if (((owner == null) || ((owner instanceof LoginFrame)))
				&& ((bannerName = keeper.getBannerName()) != null)) {
			setBackgroundImage(new ImageIcon(KeeperConst.BANNER_BG_DIR
					+ KeeperConst.FILE_SEP + bannerName).getImage());
		}

		setVisible(true);
	}

	private void initUI() {
		this.content = ((JComponent) getContentPane());
		JImagePane mainPane = new JImagePane();
		EmptyComponent ecUser = new EmptyComponent();
		EmptyComponent ecOldPsd = new EmptyComponent();
		EmptyComponent ecNewPsd = new EmptyComponent();
		EmptyComponent ecCheckPsd = new EmptyComponent();
		EmptyComponent ecPurview = new EmptyComponent();
		JImagePane buttonPane = new JImagePane();
		JCLabel lbAddAdmin = new JCLabel("首次使用，请先注册超级管理员账号");

		JCLabel lbUser = new JCLabel("用户名：");
		JCLabel lbOld = new JCLabel("旧密码：");
		JCLabel lbNew = new JCLabel(this.isAdd ? "密码" : "新密码：");
		JCLabel lbCheck = new JCLabel("密码确认");
		JCLabel lbPurview = new JCLabel("权限");
		this.txtUser = new JCTextField(this.userName);
		this.txtOld = new JCLimitedPassword(100);
		this.txtNew = new JCLimitedPassword(100);
		this.txtCheck = new JCLimitedPassword(100);
		this.cbPurview = new JCComboBox(
				new String[] { "一般用户", "受限用户" });
		this.btnOk = new JCButton("确定");
		this.btnCancel = new JCButton("取消");

		this.content.setBorder(new EmptyBorder(0, 2, 2, 2));
		this.content.setPreferredSize(new Dimension(310, (!this.isAdd)
				&& (!this.needOldPassword) ? 175 : 205));
		this.content.setLayout(new BorderLayout());
		mainPane.setLayout(new LineLayout(8, 15, 15, 15, 0, 10, 10, 1));
		mainPane.setBackground(new Color(255, 255, 255, 210));
		ecUser.setLayout(new BorderLayout());
		ecUser.setPreferredSize(new Dimension(-1, 22));
		ecOldPsd.setLayout(new BorderLayout());
		ecOldPsd.setPreferredSize(ecUser.getPreferredSize());
		ecOldPsd.setVisible((!this.isAdd) && (this.needOldPassword));
		ecNewPsd.setLayout(new BorderLayout());
		ecNewPsd.setPreferredSize(ecUser.getPreferredSize());
		ecCheckPsd.setLayout(new BorderLayout());
		ecCheckPsd.setPreferredSize(ecUser.getPreferredSize());
		ecPurview.setLayout(new BorderLayout());
		ecPurview.setPreferredSize(ecUser.getPreferredSize());
		ecPurview.setVisible((this.isAdd) && (getOwner() != null));
		lbAddAdmin.setForeground(new Color(255, 40, 110));
		lbAddAdmin.setPreferredSize(ecUser.getPreferredSize());
		lbAddAdmin.setVisible((this.isAdd) && (getOwner() == null));
		buttonPane.setLayout(new LineLayout(5, 7, 7, 7, 0, 10, 10, 0));
		buttonPane.setBackground(new Color(255, 255, 255, 150));
		buttonPane.setPreferredSize(new Dimension(-1, 32));
		this.txtUser.setEditable(this.isAdd);
		lbUser.setPreferredSize(new Dimension(60, -1));
		lbOld.setPreferredSize(lbUser.getPreferredSize());
		lbNew.setPreferredSize(lbUser.getPreferredSize());
		lbCheck.setPreferredSize(lbUser.getPreferredSize());
		lbPurview.setPreferredSize(lbUser.getPreferredSize());
		this.btnOk.setPreferredSize(new Dimension(69, 21));
		this.btnOk.addActionListener(this);
		this.btnCancel.setPreferredSize(this.btnOk.getPreferredSize());
		this.btnCancel.addActionListener(this);

		ecUser.add(lbUser, "West");
		ecUser.add(this.txtUser, "Center");
		ecOldPsd.add(lbOld, "West");
		ecOldPsd.add(this.txtOld, "Center");
		ecNewPsd.add(lbNew, "West");
		ecNewPsd.add(this.txtNew, "Center");
		ecCheckPsd.add(lbCheck, "West");
		ecCheckPsd.add(this.txtCheck, "Center");
		ecPurview.add(lbPurview, "West");
		ecPurview.add(this.cbPurview, "Center");
		buttonPane.add(this.btnOk, "End");
		buttonPane.add(this.btnCancel, "End");
		mainPane.add(lbAddAdmin, "StartFill");
		mainPane.add(ecUser, "StartFill");
		mainPane.add(ecOldPsd, "StartFill");
		mainPane.add(ecNewPsd, "StartFill");
		mainPane.add(ecCheckPsd, "StartFill");
		mainPane.add(ecPurview, "StartFill");
		this.content.add(buttonPane, "South");
		this.content.add(mainPane, "Center");
		setDefaultCloseOperation(0);
		pack();
		setResizable(false);
		setLocationRelativeTo(getOwner());
		UIUtil.escAndEnterAction(this, this.btnOk, new AbstractAction() {
			private static final long serialVersionUID = 7092223290373790975L;

			public void actionPerformed(ActionEvent e) {
				UserInfoDialog.this.cancel();
			}
		});
		if (this.isAdd) {
			this.txtUser.requestFocus();
		} else if (this.needOldPassword) {
			this.txtOld.requestFocus();
		} else {
			this.txtNew.requestFocus();
		}

		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				UserInfoDialog.this.cancel();
			}
		});
	}

	private void submit() {
		this.userName = (this.isAdd ? this.txtUser.getText() : this.userName);
		String oldPsd = this.needOldPassword ? new String(
				this.txtOld.getPassword()) : null;
		String newPsd = new String(this.txtNew.getPassword());
		String checkPsd = new String(this.txtCheck.getPassword());
		String retInfo = null;
		String newCiphertext = null;

		if ((this.isAdd) && (!User.isAllowedName(this.userName))) {
			this.txtUser.requestFocus();
			retInfo = "用户名不能为空且不能出现半角逗号(,)";
		} else if ((!this.isAdd) && (this.needOldPassword)
				&& (!User.isAllowedPassword(oldPsd))) {
			this.txtOld.requestFocus();
			retInfo = "密码长度不能小于4位！";
		} else if (!User.isAllowedPassword(newPsd)) {
			this.txtNew.requestFocus();
			retInfo = "密码长度不能小于4位！";
		} else if (!User.isAllowedPassword(checkPsd)) {
			this.txtCheck.requestFocus();
			retInfo = "密码长度不能小于4位！";
		}

		if (retInfo == null) {
			boolean checkOk = newPsd.equals(checkPsd);

			if (checkOk) {
				newCiphertext = User.createCiphertext(this.userName, newPsd);
				List<User> users = UserDAO.getUsers(new Criterion[] { Restrictions
						.eq("name", this.userName) });

				if (users.isEmpty()) {
					retInfo = this.isAdd ? null : "该用户不存在";
				} else if (this.isAdd) {
					this.txtUser.requestFocus();
					retInfo = "该用户已存在";
				} else {
					this.user = ((User) users.get(0));

					if ((this.needOldPassword)
							&& (!User.createCiphertext(this.userName, oldPsd)
									.equals(this.user.getPassword()))) {
						this.txtOld.requestFocus();
						this.txtOld.setText(null);
						retInfo = "旧密码错误！";
					}
				}

			} else {
				this.txtCheck.requestFocus();
				retInfo = "两次密码输入不一致！";
			}
		}

		if (retInfo == null) {
			if (this.isAdd) {
				String purview = String.valueOf(this.cbPurview
						.getSelectedItem());
				this.user = new User();
				this.user.setName(this.userName);
				this.user.setPassword(newCiphertext);
				this.user.setPurview(getOwner() == null ? 0 : User
						.getPurviewByName(purview));
				UserDAO.addUser(this.user);
				retInfo = "用户添加成功";
			} else {
				this.user.setPassword(newCiphertext);
				UserDAO.updateUser(this.user);
				retInfo = "密码修改成功，请牢记新密码！";
			}

			JCMessageBox.createInformationMessageBox(this, getTitle(), retInfo)
					.open();
			dispose();
		} else {
			JCMessageBox.createErrorMessageBox(this, getTitle(), retInfo)
					.open();
		}
	}

	public User getUser() {
		return this.user;
	}

	private void cancel() {
		this.user = null;
		dispose();
	}

	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();

		if (source == this.btnOk) {
			submit();
		} else if (source == this.btnCancel) {
			cancel();
		}
	}
}